package com.zzj.ecology.admin.controller;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;

/**
 * https://www.cnblogs.com/scuury/p/10093287.html
 * https://www.jianshu.com/p/8865433102cf
 */
@Controller
@RequestMapping("/pdf")
public class PDFController {

    /**
     * windows
     * Runtime.getRuntime().exec("explorer 文件路径“);
     *
     * linux.
     * Runtime.getRuntime().exec("nautilus 文件路径“);
     *
     * windows & linux
     * Desktop.getDesktop().open(new File("文件路径"));
     */
    @RequestMapping("/text/run")
    public void test() {
        try {
            Runtime.getRuntime().exec("explorer D:\\物.xlsx"); //OK
            //Desktop.getDesktop().open(new File("D://物.xlsx"));//NG
        } catch (IOException e) {
            e.printStackTrace();
        }

//        Runtime run = Runtime.getRuntime();
//        try {
//
//            Process p = run.exec("D:\\火狐\\firefox.exe");
//　　　　　　　　  //可在此处写上面的cmd代码
//            //单纯打开一个exe程序，只用这个就可以
//            //启动另一个进程来执行命令  ，路径\要使用双\，表示转义
//
//            //以下可用做CMD模式下命令
//            BufferedInputStream BI = new BufferedInputStream(p.getInputStream());
//            //BufferedInputStream提供缓存服务，读取输入流中的数据，缓存区大小貌似可以自己设定
//
//            BufferedReader BR = new BufferedReader(new InputStreamReader(BI));
//            String lineMessage;
//            while ((lineMessage = BR.readLine()) != null)
//
//                System.out.println(lineMessage);// 打印输出信息
//
//            //检查命令是否执行失败。
//            if (p.waitFor() != 0) {
//                if (p.exitValue() == 1)//0表示正常结束，1：非正常结束
//                    System.err.println("命令执行失败!");
//            }
//            BR.close();
//            BI.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

//    com.itextpdf.text.Document：这是iText库中最常用的类，它代表了一个pdf实例。如果你需要从零开始生成一个PDF文件，你需要使用这个Document类。首先创建（new）该实例，然后打开（open）它，并添加（add）内容，最后关闭（close）该实例，即可生成一个pdf文件。
//    com.itextpdf.text.Paragraph：表示一个缩进的文本段落，在段落中，你可以设置对齐方式，缩进，段落前后间隔等。
//    com.itextpdf.text.Chapter：表示PDF的一个章节，他通过一个Paragraph类型的标题和整形章数创建。
//    com.itextpdf.text.Font：这个类包含了所有规范好的字体，包括family of font，大小，样式和颜色，所有这些字体都被声明为静态常量。
//    com.itextpdf.text.List：表示一个列表；
//    com.itextpdf.text.pdf.PDFPTable：表示一个表格；
//    com.itextpdf.text.Anchor：表示一个锚，类似于HTML页面的链接。
//    com.itextpdf.text.pdf.PdfWriter：当这个PdfWriter被添加到PdfDocument后，所有添加到Document的内容将会写入到与文件或网络关联的输出流中。
//    com.itextpdf.text.pdf.PdfReader：用于读取PDF文件；

    /**
     * 创建一个PDF文件
     */
    @RequestMapping("/c1")
    public void createPDF1() {
        Document document = new Document();
        try {
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("D://HelloWorld.pdf"));
            document.open();
            document.add(new Paragraph("A Hello World PDF document."));
            document.close();
            writer.close();
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {

        }
    }

    /**
     * 给PDF文件设置各种属性，如作者名字，创建日期，创建者，或者标题
     */
    @RequestMapping("/c2")
    public void createPDF2() {
        Document document = new Document();
        try
        {
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("SetAttributeExample.pdf"));
            document.open();
            document.add(new Paragraph("Some content here"));

            //Set attributes here
            document.addAuthor("Lokesh Gupta");
            document.addCreationDate();
            document.addCreator("HowToDoInJava.com");
            document.addTitle("Set Attribute Example");
            document.addSubject("An example to show how attributes can be added to pdf files.");

            document.close();
            writer.close();
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 给PDF文件中添加图片。例子中图片来源包含了两种方式：本地图片或URL
     */
    @RequestMapping("/c3")
    public void createPDF3() {
        Document document = new Document();
        try
        {
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("AddImageExample.pdf"));
            document.open();
            document.add(new Paragraph("Image Example"));

            //Add Image
            Image image1 = Image.getInstance("C:\\temp.jpg");
            //Fixed Positioning
            image1.setAbsolutePosition(100f, 550f);
            //Scale to new height and new width of image
            image1.scaleAbsolute(200, 200);
            //Add to document
            document.add(image1);

            String imageUrl = "http://www.eclipse.org/xtend/images/java8_logo.png";
            Image image2 = Image.getInstance(new URL(imageUrl));
            document.add(image2);

            document.close();
            writer.close();
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * PDF文件中创建表格
     */
    @RequestMapping("/c4")
    public void createPDF4() {
        Document document = new Document();
        try {
            PdfWriter writer = PdfWriter.getInstance(document,
                    new FileOutputStream("AddTableExample.pdf"));
            document.open();

            PdfPTable table = new PdfPTable(3); // 3 columns.
            table.setWidthPercentage(100); // Width 100%
            table.setSpacingBefore(10f); // Space before table
            table.setSpacingAfter(10f); // Space after table

            // Set Column widths
            float[] columnWidths = { 1f, 1f, 1f };
            table.setWidths(columnWidths);

            PdfPCell cell1 = new PdfPCell(new Paragraph("Cell 1"));
            cell1.setBorderColor(BaseColor.BLUE);
            cell1.setPaddingLeft(10);
            cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);

            PdfPCell cell2 = new PdfPCell(new Paragraph("Cell 2"));
            cell2.setBorderColor(BaseColor.GREEN);
            cell2.setPaddingLeft(10);
            cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell2.setVerticalAlignment(Element.ALIGN_MIDDLE);

            PdfPCell cell3 = new PdfPCell(new Paragraph("Cell 3"));
            cell3.setBorderColor(BaseColor.RED);
            cell3.setPaddingLeft(10);
            cell3.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell3.setVerticalAlignment(Element.ALIGN_MIDDLE);

            // To avoid having the cell border and the content overlap, if you
            // are having thick cell borders
            // cell1.setUserBorderPadding(true);
            // cell2.setUserBorderPadding(true);
            // cell3.setUserBorderPadding(true);

            table.addCell(cell1);
            table.addCell(cell2);
            table.addCell(cell3);

            document.add(table);

            document.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * PDF文件里创建列表
     */
    @RequestMapping("/c5")
    public void createPDF5() {
        Document document = new Document();
        try
        {
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("ListExample.pdf"));
            document.open();
            document.add(new Paragraph("List Example"));

            //Add ordered list
            List orderedList = new List(List.ORDERED);
            orderedList.add(new ListItem("Item 1"));
            orderedList.add(new ListItem("Item 2"));
            orderedList.add(new ListItem("Item 3"));
            document.add(orderedList);

            //Add un-ordered list
            List unorderedList = new List(List.UNORDERED);
            unorderedList.add(new ListItem("Item 1"));
            unorderedList.add(new ListItem("Item 2"));
            unorderedList.add(new ListItem("Item 3"));
            document.add(unorderedList);

            //Add roman list
            RomanList romanList = new RomanList();
            romanList.add(new ListItem("Item 1"));
            romanList.add(new ListItem("Item 2"));
            romanList.add(new ListItem("Item 3"));
            document.add(romanList);

            //Add Greek list
            GreekList greekList = new GreekList();
            greekList.add(new ListItem("Item 1"));
            greekList.add(new ListItem("Item 2"));
            greekList.add(new ListItem("Item 3"));
            document.add(greekList);

            //ZapfDingbatsList List Example
            ZapfDingbatsList zapfDingbatsList = new ZapfDingbatsList(43, 30);
            zapfDingbatsList.add(new ListItem("Item 1"));
            zapfDingbatsList.add(new ListItem("Item 2"));
            zapfDingbatsList.add(new ListItem("Item 3"));
            document.add(zapfDingbatsList);

            //List and Sublist Examples
            List nestedList = new List(List.UNORDERED);
            nestedList.add(new ListItem("Item 1"));

            List sublist = new List(true, false, 30);
            sublist.setListSymbol(new Chunk("", FontFactory.getFont(FontFactory.HELVETICA, 6)));
            sublist.add("A");
            sublist.add("B");
            nestedList.add(sublist);

            nestedList.add(new ListItem("Item 2"));

            sublist = new List(true, false, 30);
            sublist.setListSymbol(new Chunk("", FontFactory.getFont(FontFactory.HELVETICA, 6)));
            sublist.add("C");
            sublist.add("D");
            nestedList.add(sublist);

            document.add(nestedList);

            document.close();
            writer.close();
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * PDF文件内容设置样式的例子，例子中包含了字体、章、节的使用
     */
    @RequestMapping("/c6")
    public void createPDF6() {
        Font blueFont = FontFactory.getFont(FontFactory.HELVETICA, 8, Font.NORMAL, new CMYKColor(255, 0, 0, 0));
        Font redFont = FontFactory.getFont(FontFactory.COURIER, 12, Font.BOLD, new CMYKColor(0, 255, 0, 0));
        Font yellowFont = FontFactory.getFont(FontFactory.COURIER, 14, Font.BOLD, new CMYKColor(0, 0, 255, 0));
        Document document = new Document();
        try
        {
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("StylingExample.pdf"));
            document.open();
            //document.add(new Paragraph("Styling Example"));

            //Paragraph with color and font styles
            Paragraph paragraphOne = new Paragraph("Some colored paragraph text", redFont);
            document.add(paragraphOne);

            //Create chapter and sections
            Paragraph chapterTitle = new Paragraph("Chapter Title", yellowFont);
            Chapter chapter1 = new Chapter(chapterTitle, 1);
            chapter1.setNumberDepth(0);

            Paragraph sectionTitle = new Paragraph("Section Title", redFont);
            Section section1 = chapter1.addSection(sectionTitle);

            Paragraph sectionContent = new Paragraph("Section Text content", blueFont);
            section1.add(sectionContent);

            document.add(chapter1);

            document.close();
            writer.close();
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }


    private static String USER_PASSWORD = "password";
    private static String OWNER_PASSWORD = "lokesh";
    /**
     * pdf文件生产保护密码，如下，使用writer.setEncryption()方法即可给pdf文件设置密码
     */
    @RequestMapping("/c7")
    public void createPDF7() {
        try
        {
            OutputStream file = new FileOutputStream(new File("PasswordProtected.pdf"));
            Document document = new Document();
            PdfWriter writer = PdfWriter.getInstance(document, file);

            writer.setEncryption(USER_PASSWORD.getBytes(),
                    OWNER_PASSWORD.getBytes(), PdfWriter.ALLOW_PRINTING,
                    PdfWriter.ENCRYPTION_AES_128);

            document.open();
            document.add(new Paragraph("Password Protected pdf example !!"));
            document.close();
            file.close();

        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

//    PdfWriter.ALLOW_PRINTING
//    PdfWriter.ALLOW_ASSEMBLY
//    PdfWriter.ALLOW_COPY
//    PdfWriter.ALLOW_DEGRADED_PRINTING
//    PdfWriter.ALLOW_FILL_IN
//    PdfWriter.ALLOW_MODIFY_ANNOTATIONS
//    PdfWriter.ALLOW_MODIFY_CONTENTS
//    PdfWriter.ALLOW_SCREENREADERS
    /**
     * 设置一些权限用于限制其它用户访问PDF文件，如下是一些权限设置值
     * 你可以通过对不同的值执行或操作来实现多权限设置，举个例子：PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_COPY
     */
    @RequestMapping("/c8")
    public void createPDF8() {
        try {
            OutputStream file = new FileOutputStream(new File(
                    "LimitedAccess.pdf"));
            Document document = new Document();
            PdfWriter writer = PdfWriter.getInstance(document, file);

            writer.setEncryption("".getBytes(), "".getBytes(),
                    PdfWriter.ALLOW_PRINTING , //Only printing allowed; Try to copy text !!
                    PdfWriter.ENCRYPTION_AES_128);

            document.open();
            document.add(new Paragraph("Limited Access File !!"));
            document.close();
            file.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 使用iText库实现PDF文件的读取和修改。在这个例子中，我将读取一个PDF文件，并往每一页添加一些内容
     */
    @RequestMapping("/c9")
    public void createPDF9() {
        try
        {
            //Read file using PdfReader
            PdfReader pdfReader = new PdfReader("HelloWorld.pdf");

            //Modify file using PdfReader
            PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream("HelloWorld-modified.pdf"));

            Image image = Image.getInstance("temp.jpg");
            image.scaleAbsolute(100, 50);
            image.setAbsolutePosition(100f, 700f);

            for(int i=1; i<= pdfReader.getNumberOfPages(); i++)
            {
                PdfContentByte content = pdfStamper.getUnderContent(i);
                content.addImage(image);
            }

            pdfStamper.close();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    /**
     * 往HttpServletResponse的输出流中写入一些PDF内容。
     * 在CS环境中，当你需要将PDF文件转成流的形式的时候，这非常有用
     */
    @RequestMapping("/c10")
    public void createPDF10(HttpServletResponse response) {
        Document document = new Document();
        try{

            PdfWriter.getInstance(document, response.getOutputStream());
            document.open();
            document.add(new Paragraph("howtodoinjava.com"));
            document.add(new Paragraph(new Date().toString()));
            //Add more content here

            //下载
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment;fileName="
                    + URLEncoder.encode("D:\\ABC.PDF", "UTF-8"));
        }catch(Exception e){
            e.printStackTrace();
        }
        document.close();
    }

    /**
     * 以JSON的方式 ajax 方式下载PDF
     * @param response
     * @return
     * @throws DocumentException
     */
    @RequestMapping("/createPDF")
    //@ResponseBody
    public String  createPDF(HttpServletResponse response) throws DocumentException {

        // 模板路径 关于路径最好放在配置文件中，我这里只想说明问题
        String templatePath = "C:\\Users\\zy962\\Desktop\\temp.pdf";
        // 生成文件路径
        String filename = "testpdf.pdf";

        // 创建对象
//        PdfEntity entity = new PdfEntity();//自定义对象
//        entity.setDogNo("NO123456");
//        entity.setName("周毅");
//        entity.setAge(26);
//        entity.setDogYear(4);
//        entity.setBrithday("93.11.18");
//        entity.setReason("已经失去了追人的能力。陷入了一个死循环：我主动找她吧，要是对我没感觉，找了不理我怎么办？于是还没尝试，就不去招惹别人了。");
//        entity.setRemark("并不是每一个单身的人，都代表可撩的状态，有的人早已经对恋爱不抱什么希望。只想好好学习，好好工作，然后发财。");
//        entity.setLevel("到了我这种境界后，就可以和寂寞和睦相处。若有了独自活下去的觉悟，慢慢变老也会充满乐趣。");
//        entity.setAbility("非常羡慕那些能一喜欢/一追就是几年的人，这种恒心，在他来说，一个月、不一个周都做不到，两天应该也许大概能做到。");
//        entity.setSummary("综上结论，面向对象是不存在的，面向过程是不存在的，汪汪汪一只。");
//
        Map<String, Object> datas = new HashMap<String, Object>();
//        datas.put("name", entity.getName());// name key是制造ＰＤＦ模板时用到的key
//        datas.put("dogNo", entity.getDogNo());
//        datas.put("age", entity.getAge());
//        datas.put("dogYear", entity.getDogYear());
//        datas.put("brithday", entity.getBrithday());
//        datas.put("reason", entity.getReason());
//        datas.put("remark", entity.getRemark());
//        datas.put("level", entity.getLevel());
//        datas.put("ability", entity.getAbility());
//        datas.put("summary", entity.getSummary());

        PdfReader reader;
        OutputStream os = null;
        ByteArrayOutputStream baos = null;
        PdfStamper stamper;

        try {
            os = response.getOutputStream();
            // 读入pdf表单
            reader = new PdfReader(templatePath);
            baos = new ByteArrayOutputStream();
            // 根据表单生成一个新的pdf
            stamper = new PdfStamper(reader, baos);
            // 获取pdf表单
            AcroFields formTexts = stamper.getAcroFields();

            // 设置字体(这里设置为系统字体，你也可以引入其他的字体)，不设置很可能，中文无法显示。
            BaseFont bf = BaseFont.createFont("C:/WINDOWS/Fonts/SIMSUN.TTC,1",
                    BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            formTexts.addSubstitutionFont(bf);

            // 数据查询后，值的植入 强烈推荐键值方式，其他方式很容易混
            Set<String> keySet =  datas.keySet();
            for (String key : keySet) {
                formTexts.setField(key, datas.get(key).toString());
            }

            stamper.setFormFlattening(true); // 这个必须设
            stamper.close();

            // 创建一个pdf实例
            Document document = new Document();
            PdfCopy copy = new PdfCopy(document, os);
            document.open();
            PdfImportedPage importedPage = copy.getImportedPage(new PdfReader(baos.toByteArray()), 1);
            copy.addPage(importedPage);
            document.close(); // open和close一套


//            // 通过域名获取所在页和坐标，左下角为起点
//            String imgpath="e:/aa.png";
//            int pageNo = form.getFieldPositions("img").get(0).page;
//            Rectangle signRect = form.getFieldPositions("img").get(0).position;
//            float x = signRect.getLeft();
//            float y = signRect.getBottom();
//            // 读图片
//            Image image = Image.getInstance(imgpath);
//            // 获取操作的页面
//            PdfContentByte under = ps.getOverContent(pageNo);
//            // 根据域的大小缩放图片
//            image.scaleToFit(signRect.getWidth(), signRect.getHeight());
//            // 添加图片
//            image.setAbsolutePosition(x, y);
//            under.addImage(image);

            // 强制下载
            //response.reset();
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment;fileName="
                    + URLEncoder.encode(filename, "UTF-8"));

        } catch (IOException e) {
            e.printStackTrace();
        } finally { // 最后一定要关闭流
            try {
                baos.close();
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return "成功，请去查看";
    }

    /**
     *
     */
    @RequestMapping("/c11")
    public void createPDF11(HttpServletResponse response) {
        InputStream inputStream = null;
        XSSFWorkbook workbook = null;
        try {
            inputStream = this.getClass().getClassLoader().getResourceAsStream("documents/form1.xlsx");
            workbook = (XSSFWorkbook) WorkbookFactory.create(inputStream);

            //下载文件
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("form1.pdf", "UTF-8"));
            //response.setHeader("Content-Disposition", "inline; filename=form1.pdf");

            OutputStream outputStream = response.getOutputStream();

            //写出到浏览器，用于预览
            workbook.write(outputStream);
            outputStream.flush();
        } catch (Exception e) {
        } finally {

        }
    }

    public void converXlsxToPDF(String[] args) throws Exception{

        FileInputStream input_document = new FileInputStream(new File("C:\\excel_to_pdf.xls"));
        // Read workbook into HSSFWorkbook
        XSSFWorkbook my_xls_workbook = new XSSFWorkbook(input_document);
        // Read worksheet into HSSFSheet
        XSSFSheet my_worksheet = my_xls_workbook.getSheetAt(0);
        // To iterate over the rows
        Iterator<Row> rowIterator = my_worksheet.iterator();
        //We will create output PDF document objects at this point
        Document iText_xls_2_pdf = new Document();
        PdfWriter.getInstance(iText_xls_2_pdf, new FileOutputStream("Excel2PDF_Output.pdf"));
        iText_xls_2_pdf.open();
        //we have two columns in the Excel sheet, so we create a PDF table with two columns
        //Note: There are ways to make this dynamic in nature, if you want to.
        PdfPTable my_table = new PdfPTable(2);
        //We will use the object below to dynamically add new data to the table
        PdfPCell table_cell;
        //Loop through rows.
        while(rowIterator.hasNext()) {
            Row row = rowIterator.next();
            Iterator<Cell> cellIterator = row.cellIterator();
            while(cellIterator.hasNext()) {
                Cell cell = cellIterator.next(); //Fetch CELL
                switch(cell.getCellType()) { //Identify CELL type
                    //you need to add more code here based on
                    //your requirement / transformations
                    case Cell.CELL_TYPE_STRING:
                        //Push the data from Excel to PDF Cell
                        table_cell=new PdfPCell(new Phrase(cell.getStringCellValue()));
                        //feel free to move the code below to suit to your needs
                        my_table.addCell(table_cell);
                        break;
                }
                //next line
            }

        }
        //Finally add the table to PDF document
        iText_xls_2_pdf.add(my_table);
        iText_xls_2_pdf.close();
        //we created our pdf file..
        input_document.close(); //close xls
    }


    /**
     *
     */
    @RequestMapping("/c")
    public void createPDF() {

    }

}
